#ifndef __CQUEUE_H__
#define __CQUEUE_H__

#include <functional>
#include "plat/nonecopyable.h"

#define QUEUE_DEFAULT_SIZE 10

/// @brief 队列，使用静态内存分配
/// @tparam T 
/// @tparam QUEUE_CAPACITY 
///         只要队列不满，就不会有多线程安全问题, 不需要加锁 
template<typename T, int QUEUE_CAPACITY = QUEUE_DEFAULT_SIZE>
class Queue : public NoneCopyable
{
public:
    explicit Queue(){}
    virtual ~Queue(){}

public:
    bool EnQueue(T elem)
    {
        if(IsFull())
        {
            return false;
        }

        m_buffuer[m_rearPos] = elem;
        m_count++;
        m_rearPos = (m_rearPos + 1) % m_maxCount;
        return true;
    }

    T DeQueue()
    {
        T  elem;

        if(IsEmpty())
        {
            return elem;
        }

        elem = m_buffuer[m_frontPos];
        m_count--;
        m_frontPos = (m_frontPos + 1) % m_maxCount;
        return elem;
    }
    
    T GetFront()
    {
        T  elem;
        if(GetCount() > 0)
        {
            elem = m_buffuer[m_frontPos];
        }

        return elem;
    }

    int GetCount()
    {
        return m_count;
    }

    int GetCapacity()
    {
        return m_maxCount;
    }

    int IsFull()
    {
	    return GetCount() == m_maxCount;
    }

    int IsEmpty()
    {
	    return GetCount() == 0;
    }
    
    int GetSpaceFree()
    {
	    return (m_maxCount - GetCount());
    }

    void Clear()
    {
        m_frontPos = 0;
        m_rearPos = 0;
    }

    void Foreach(const std::function<void(T &t)> &&func)
    {
        int count = GetCount();
        int index = m_frontPos;
        for(int i = 0; i < count; i++)
        {
            func(m_buffuer[index]);
            index = (index + 1) % m_maxCount;
        }
    }

private:
    T  m_buffuer[QUEUE_CAPACITY];
    int m_maxCount = QUEUE_CAPACITY;

    int m_count = 0;
    int m_frontPos = 0;
    int m_rearPos = 0;
};

#endif // __CQUEUE_H__
